import sys
import os
import re

filepath = sys.argv[1]
outfilepath = sys.argv[2]
print(filepath)

id2tonal = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]

tonal2id = {
    'C': 0,
    'C#': 1, 'Db': 1,
    'D': 2,
    'D#': 3, 'Eb': 3, 'EB': 3,
    'E': 4,
    'F': 5,
    'F#': 6, 'Gb': 6,
    'G': 7,
    'G#': 8, 'Ab': 8,
    'A': 9,
    'A#': 10, 'Bb': 10,
    'B': 11,

    'c': 0,
    'c#': 1, 'db': 1,
    'd': 2,
    'd#': 3, 'eb': 3,
    'e': 4,
    'f': 5,
    'f#': 6, 'gb': 6,
    'g': 7,
    'g#': 8, 'ab': 8,
    'a': 9,
    'a#': 10, 'bb': 10,
    'b': 11
}


def conTonal_tonal(tonal, delta):
    s = tonal.split(".")
    tId = tonal2id[s[0]]
    t = id2tonal[(tId+delta+24) % 12]
    if s[1] == "minor":
        t = t.lower()
    return t+"."+s[1]


def replace_tonal(str):
    return "("+conTonal_tonal(str.group(1), delta)+","+str.group(2)+")"


def replace_note(istr):
    s = istr.group()
    if s != '':
        i = int(s)
        if i > 0:
            i += delta
        return str(i)


def replace_melody(str):
    return re.sub(r"([0-9]*)",
                  replace_note, str.group(), flags=re.I | re.M | re.S)


def replace_2dMelody(istr):
    s = istr.group(1)
    if s != '':
        i = int(s)
        if i > 0:
            i += delta
    return "("+str(i)+","+istr.group(2)+")"


def processStr(istr):
    istr = re.sub(r"\(([a-zA-Z\.# ]*),([0-9 ]*)\)",
                  replace_tonal, istr, flags=re.I | re.M | re.S)
    istr = re.sub(r"\[([0-9\,\]\[ \]]*)\]\|",
                  replace_melody, istr, flags=re.I | re.M | re.S)
    istr = re.sub(r"\(([0-9 ]*),([0-9 ]*)\)",
                  replace_2dMelody, istr, flags=re.I | re.M | re.S)
    return(istr)


def processFile(path, outpath):
    global delta
    with open(path) as fp:
        istr = fp.read()
        try:
            os.mkdir(outpath)
        except Exception:
            pass
        for i in range(-6, 7):
            delta = i
            res = processStr(istr)
            with open(f"{outpath}/delta{i}.txt", "w") as ofp:
                ofp.write(res)


processFile(filepath, outfilepath)
